﻿using System.Collections.Generic;
using IQIGame.Onigao.Framework;

namespace IQIGame.Onigao.GamePlay
{
    /// <summary>
    /// 表现层状态记录 注意需要与逻辑层的CustomPropertyComponent保持一致
    /// </summary>
    public class CustomPropertyViewComponent : TComponent
    {
        public UnitView unit;
        
        public readonly Dictionary<int, TAny> propertyHash = new Dictionary<int, TAny>((int)ECustomProperty.Max);
        // 限制优先级列表，优先级最高的在链表最前  暂时不需要考虑优先级，只考虑层数，那么暂时不需要单独存储限制
        // public readonly Dictionary<EUnitStateLimit, BetterLinkedList<int>> limitHash = new Dictionary<EUnitStateLimit, BetterLinkedList<int>>((int)EUnitStateLimit.Max);
        
        # region Property
        public T GetProperty<T>(ECustomProperty rType)
        {
            var nKey = (int)rType;
            return this.GetProperty<T>(nKey);
        }

        private T GetProperty<T>(int nKey)
        {
            if (this.propertyHash.TryGetValue(nKey, out var rAny))
            {
                return TAnyHelper.GetAny<T>(rAny);
            }

            return default(T);
        }

        public void SetProperty<T>(ECustomProperty rType, T rValue, ETAnyType rAnyType)
        {
            var nKey = (int)rType;
            this.SetProperty(nKey, rValue, rAnyType);
        }
        
        private void SetProperty<T>(int nKey, T rValue, ETAnyType rAnyType)
        {
            if (!this.TryGetPropertyAny(nKey, out var rAny))
            {
                rAny = this.AddProperty(nKey, rAnyType);
            }
            TAnyHelper.SetAny(rAny, rValue);
        }
        
        private TAny AddProperty(int nKey, ETAnyType rAnyType)
        {
            this.propertyHash[nKey] = TAnyHelper.NewAny(rAnyType);
            return this.propertyHash[nKey];
        }
        
        private bool TryGetPropertyAny(int nKey, out TAny rAny)
        {
            return this.propertyHash.TryGetValue(nKey, out rAny);
        }
        #endregion

        #region Limit
        // public int GetLimit(EUnitStateLimit rLimit)
        // {
        //     if (this.limitHash.TryGetValue(rLimit, out var rList) && rList.Count > 0)
        //     {
        //         return rList.First;
        //     }
        //
        //     return 0;
        // }
        //
        // public void ModifyLimit(EUnitStateLimit rLimit, int nPriority, bool bAdd = true)
        // {
        //     if (nPriority < 0)
        //     {
        //         nPriority = int.MaxValue;
        //     }
        //
        //     if (!this.limitHash.TryGetValue(rLimit, out var rList))
        //     {
        //         rList = new BetterLinkedList<int>();
        //         this.limitHash.Add(rLimit, rList);
        //     }
        //
        //     // 找到优先级<= 自己的最靠前的那个
        //     var rNode = rList.FirstNode;
        //     for (; rNode != null; rNode = rNode.next)
        //     {
        //         if (rNode.value <= nPriority)
        //         {
        //             break;
        //         }
        //     }
        //     
        //     if (bAdd)
        //     {
        //         rList.AddBefore(rNode, nPriority);
        //     }
        //     else if(rNode?.value == nPriority)
        //     {
        //         rList.RemoveNode(rNode);
        //     }
        // }
        #endregion
        
        protected override void OnDispose()
        {
            this.propertyHash.Clear();
            // this.limitHash.Clear();
        }

        public override void OnCreate(TEntity entity)
        {
            this.unit = entity as UnitView;
        }
    }
}